home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Electronics Plus 3
/
PC Electronics Plus 3.iso
/
coil01
/
coil.c
next >
Wrap
C/C++ Source or Header
|
1996-02-28
|
8KB
|
462 lines
/* Main program for electrical self inductance of a coil.
*
* Program by Steve Moshier
* moshier@world.std.com
*
* Last rev: December, 1992
* Version 0.1: February, 1996 (Menu item to choose inches or centimeters)
*/
double floor(), sqrt(), exp(), log(), pow();
double skin(), helsol(), nagaoka(), rsol(), squaresol();
/* 0 for centimeters, 1 for inches */
int INCHES = 1;
double diameter = 0.0;
double length = 0.0;
double dbundle = 0.0;
double outer = 0.0;
double frequency = 0.0;
double N = 0.0;
double gauge = 0.0;
int geometry = 1;
#define PI 3.14159265358979323846
extern double MACHEP; /* = 2.2e-16; */
extern double MAXNUM; /* = 1.7e38; */
char str[40];
main()
{
double b, p, d, l, a, L, s;
printf( "Steve Moshier's Inductance Calculator v0.1\n\n" );
loop:
printf( "\nGeometry of coil:\n1 Circular solenoidal current sheet" );
printf( "\n2 Straight round wire" );
printf( "\n3 N-turn circular loop\n4 Circular toroid, circular winding" );
printf( "\n5 Multi-layer square solenoid (low precision)" );
printf( "\n6 Circular torus ring, rectangular winding" );
printf( "\n7 Multi-layer circular solenoid" );
printf( "\n8 Single-layer circular solenoid of round wire" );
printf( "\n9 Single-layer square solenoid" );
printf( "\n10 Wire gauge calculation" );
if (INCHES)
printf( "\n11 Change units to centimeters (now inches)\n");
else
printf( "\n11 Change units to inches (now centimeters)\n");
printf( " Choose menu item number (%d) ? ", geometry );
gets( str );
sscanf( str, "%d", &geometry );
printf( "%d\n", geometry );
if( geometry < 0 )
exit(0); /* graceful exit to monitor */
if( (geometry <= 0) || (geometry > 11) )
goto operror;
if( geometry == 10 )
{
wire();
goto loop;
}
if( geometry == 11 )
{
if (INCHES)
INCHES = 0;
else
INCHES = 1;
goto loop;
}
/* Thick circular solenoid
*/
if( geometry == 7 )
{
getnum( "Average diameter", &diameter, 0 );
getrad:
getnum( "Radial depth of winding", &dbundle, 0 );
if( dbundle > diameter )
{
printf( "Depth cannot exceed diameter. Try again.\n" );
goto getrad;
}
getnum( "Length of winding", &length, 0 );
getnum( "Total number of turns", &N, 1 );
if( INCHES )
{
d = 2.54 * diameter;
l = 2.54 * length;
a = 2.54 * dbundle;
}
else
{
d = diameter;
l = length;
a = dbundle;
}
L = rsol( 0.5*d, l, a, N );
goto done;
}
/* Circular torus ring of rectangular cross section
* Ref: Skilling 1948
*/
if( geometry == 6 )
{
getnum( "Inner diameter of circular torus ring", &diameter, 1 );
getnum( "Radial width of winding cross section", &dbundle, 0 );
getnum( "Height of winding cross section", &length, 0 );
getnum( "Total number of turns", &N, 0 );
if( INCHES )
{
d = 2.54 * diameter;
l = 2.54 * length;
a = 2.54 * dbundle;
}
else
{
d = diameter;
l = length;
a = dbundle;
}
d *= 0.5;
L = 2.0e-9 * N * N * l * log( 1.0 + a/d );
goto done;
}
/* Square coil, rectangular winding cross section (thickness, length).
* Ref: Grover 1922a, CRC handbook
*/
if( (geometry == 5) || (geometry == 9) )
{
getnum( "Side of square, to center of winding thickness", &diameter, 1 );
getnum( "Winding length", &length, 1 );
if( geometry == 5 )
{
getnum( "Winding thickness", &dbundle, 0 );
}
getnum( "Total number of turns", &N, 0 );
if( INCHES )
{
d = 2.54 * diameter;
l = 2.54 * length;
a = 2.54 * dbundle;
}
else
{
d = diameter;
l = length;
a = dbundle;
}
if( geometry == 9 )
{
L = squaresol( d, l, N );
}
else
{
if( (a+l) == 0.0 )
goto operror;
s = d/(a+l);
L = 8.e-9 * d * N * N * (log(s) + 0.2235/s + 0.726 );
}
goto done;
}
/* Circular toroid
* Ref: CRC handbook
*/
if( geometry == 4 )
{
torrad:
getnum( "Radius distance from center of torus to center of winding",
&diameter, 0 );
getnum( "Diameter of circular winding", &length, 0 );
if( length > 2.0*diameter )
{
printf( "Diameter cannot exceed toroid diameter. Try again.\n" );
goto torrad;
}
getnum( "Total number of turns", &N, 0 );
if( INCHES )
{
d = 2.54 * diameter;
l = 2.54 * length;
}
else
{
d = diameter;
l = length;
}
L = 4.0e-9 * PI * N * N * (d - sqrt(d*d - 0.25*l*l));
goto done;
}
/* Solenoid, loop, or straight wire
*/
if( geometry == 2 )
{ /* straight wire */
diameter = 0.0;
}
else
{
getnum( "Diameter of winding", &diameter, 0 );
}
if( geometry == 3 )
{ /* circular loop */
length = 0.0;
}
else
{
if( geometry == 2 )
getnum( "Length of wire", &length, 0 );
else
getnum( "Length of winding", &length, 0 );
}
if( (length == 0.0) && (diameter == 0.0) )
{
L = 0.0;
goto done;
}
if( geometry == 8 )
getnum( "Wire diameter", &dbundle, 1 );
if( INCHES )
{
d = 2.54 * diameter;
l = 2.54 * length;
a = 2.54 * dbundle;
}
else
{
d = diameter;
l = length;
a = dbundle;
}
if( d == 0.0 )
goto straight;
getnum( "Total number of turns", &N, 0 );
if( l == 0.0 )
goto circloop;
if( geometry == 1 )
L = nagaoka( 0.5*d, l, N );
else
{
if( a*N > l )
{
printf( "Wire diameter too large.\n" );
goto operror;
}
L = helsol( 0.5*d, l, a, N );
}
goto done;
/* Ref: CRC handbook; Snow 1952
*/
circloop:
printf( "Circular loop.\n" );
getnum( "Please enter diameter of wire or bundle of wires", &dbundle, 1 );
if( INCHES )
a = 2.54 * dbundle;
else
a = dbundle;
p = d/a;
/* For "natural" current distribution b = -1
* For uniform current distribution b = 0 (Litz wire)
*/
b = -1.0;
if( N <= 1.0 )
s = skin(a);
else
s = 0.25;
if( a <= 0.0 )
L = MAXNUM;
else
{
L = 2.e-9 * PI * N * N * d
* ( (1.0 + (2.0*b+1.0)/(8.0*p)) * log(8.0*p) - 2.0 + s
+ (b-1.0)*(b-2.0/3.0)/(16.0*p*p));
}
goto done;
/* Ref: CRC handbook
*/
straight:
printf( "Straight piece of wire.\n" );
getnum( "Please enter diameter of wire", &dbundle, 1 );
if( INCHES )
a = 2.54 * dbundle;
else
a = dbundle;
L = 2.0e-9 * ( log(4.0*l/a) - 1.0 + skin(a) + 0.5*a/l );
done:
printf( "The inductance = %.3e henrys.\n", L );
goto loop;
operror:
printf( "? operator error\n" );
goto loop;
}
/* Skin effect correction.
* This is a close empirical approximation to a table
* found in the CRC handbook.
*/
double skin( d )
double d; /* wire diameter */
{
double s;
getnum( "Frequency in Hz, for skin effect", &frequency, 0 );
if( frequency <= 0.0 )
return( 0.25 );
s = 0.1071 * d * sqrt(frequency);
if( s > 100.0 )
{
s = 7.088/s;
}
else
{
s = 0.00546 * pow(s,5.0);
s = 0.25 * pow( 1.0+s, -0.2 );
}
return(s);
}
/* Subroutine to get value entered on keyboard
* Displays previous value and updates only if a new value is entered.
*/
getnum( s, pd, zflag )
char *s;
double *pd;
int zflag;
{
double t;
gloop:
printf( "%s (%.5lf) ? ", s, *pd );
gets(str);
if( (str[0] == '\0') && (*pd <= 0.0) )
{
t = *pd;
goto tests;
}
if( str[0] != '\0' )
{
sscanf( str, "%lf", &t );
tests:
if( zflag >= 0 )
{
if( t < 0.0 )
{
printf( " ? Negative value not allowed; try again.\n" );
goto gloop;
}
if( zflag )
{
if( t == 0.0 )
{
printf( " ? Zero value not allowed; try again.\n" );
goto gloop;
}
}
}
*pd = t;
}
/* Verify the value that will be used */
if( *pd > 1.0e4 )
printf( "%.5e\n", *pd );
else
printf( "%.5lf\n", *pd );
}
wire()
{
double b, c, d;
getnum( "American Wire Gauge (B&S) number", &gauge, -1 );
d = 0.32485 * exp( -0.11594 * gauge );
if( INCHES )
printf( "Wire diameter = %.3e inches.\n", d );
else
printf( "Wire diameter = %.3e centimeters.\n", 2.54*d );
d *= 2.54; /* convert to centimeters */
getnum( "Coil length", &length, 0 );
getnum( "Winding thickness", &dbundle, 0 );
if( INCHES )
{
b = 2.54 * length;
c = 2.54 * dbundle;
}
else
{
b = length;
c = dbundle;
}
N = 1.0;
b = floor( b/d );
if( b > 0.0 )
N = b;
c = floor( c/d );
if( c > 0.0 )
N *= c;
printf( "%.0lf turns will fit in this space.\n", N );
}